package edu.gatech.cs2340.aperturescience;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.Iterator;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import edu.gatech.cs2340.aperturescience.backend.task.SQLTasksDataSource;
import edu.gatech.cs2340.aperturescience.backend.task.Task;
import edu.gatech.cs2340.aperturescience.backend.task.TasksDataSource;
import edu.gatech.cs2340.aperturescience.map.MyGoogleMap;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.graphics.Color;
import android.location.Location;
import android.os.Bundle;
import android.text.format.DateFormat;
import android.util.Log;
import android.view.Display;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.Button;
import android.widget.CalendarView;
import android.widget.DatePicker;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.PopupWindow;
import android.widget.TextView;
import android.widget.TimePicker;
import android.widget.ToggleButton;

/**
 * TaskViewActivity manages the TaskList pane within the application
 * 
 * @author Aperture Science
 * @3/26/12
 * 
 */
public class TaskViewActivity extends Activity {
	private ListView listView;
	private PopupWindow addPopup;
	private View popupView;

	private TasksDataSource tasksSource;
	private int userid;
	private String category;
	private TaskListAdapter listAdapter;
	private FilterType filter = FilterType.NONE;
	private Date filterDate = null;
	private ArrayList<View> selected = new ArrayList<View>();
	private ArrayList<Integer> selectedids = new ArrayList<Integer>();
	private Task[] tasks;

	/**
	 * onDestroy closes the database
	 */
	protected void onDestroy() {
		super.onDestroy();
		if (tasksSource != null) {
			tasksSource.close();
		}
	}

	/**
	 * onCreate initiates the database based on the appropriate category
	 */
	public void onCreate(Bundle icicle) {
		super.onCreate(icicle);
		userid = getIntent().getIntExtra("edu.gatech.cs2340.aperturescience.uid", 0);
		
		this.category = getIntent().getExtras().getString("category", "null");
			
		if(category.equals("Today"))
		{
			this.filter = FilterType.TODAY;
			this.filterDate = new Date();
		}
		else if(category.equals("Completed"))
		{
			this.filter = FilterType.COMPLETED;
		}
		
		if (tasksSource == null) {
			tasksSource = new SQLTasksDataSource(this);
			tasksSource.open();
		}

		setContentView(R.layout.tasklistview);

		listView = (ListView) findViewById(R.id.listView1);

		loadTasks(category);

		listView.setTextFilterEnabled(true);

		final Button addTaskButton = (Button) findViewById(R.id.addTaskButton);
		final ToggleButton uncompletedButton = (ToggleButton) findViewById(R.id.uncompleted_button);
		final ToggleButton dateButton = (ToggleButton) findViewById(R.id.date_button);
		final ToggleButton[] filterButtons = new ToggleButton[] {
				uncompletedButton, dateButton };
		final Button deleteTaskButton = (Button) findViewById(R.id.deleteTaskButton);

		deleteTaskButton.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				int[] intarray = new int[selectedids.size()];
				for (int i = 0; i < intarray.length; i++) {
					Log.d("lalala", "deleting " + selectedids.get(i));
					intarray[i] = selectedids.get(i);
				}
				selectedids.clear();
				tasksSource.deleteTasks(intarray);
				loadTasks(category);
			}
		});

		Button viewMapButton = (Button) findViewById(R.id.viewMapButton);
		viewMapButton.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				Intent i = new Intent(TaskViewActivity.this, MyGoogleMap.class);
				startActivity(i);
			}
		});

		OnClickListener buttonListener = new OnClickListener() {
			@Override
			public void onClick(View view) {
				for (ToggleButton b : filterButtons) {
					if (b != view) {
						b.setChecked(false);
					}
				}
				if (!((ToggleButton) view).isChecked()) {
					filter = FilterType.NONE;
					loadTasks(category);
				} else if (view == uncompletedButton) {
					filter = FilterType.UNCOMPLETED;
					loadTasks(category);
				} else {
					filter = FilterType.DATE;

					LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
					View layout = inflater.inflate(R.layout.date_filter_picker,
							(ViewGroup) findViewById(R.id.date_picker_filter));

					Display display = getWindowManager().getDefaultDisplay();
					int width = display.getWidth();
					int height = display.getHeight();
					final PopupWindow datePopup = new PopupWindow(layout,
							width, height, true);
					datePopup.showAtLocation(layout, Gravity.CENTER, 0, 0);
					final CalendarView calendar = (CalendarView) layout
							.findViewById(R.id.calendar);
					Button okButton = (Button) layout
							.findViewById(R.id.okButton);
					okButton.setOnClickListener(new OnClickListener() {
						@Override
						public void onClick(View view) {
							filterDate = new Date(calendar.getDate());
							datePopup.dismiss();
							loadTasks(category);
						}
					});
				}
			}
		};
		uncompletedButton.setOnClickListener(buttonListener);
		dateButton.setOnClickListener(buttonListener);
		addTaskButton.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View view) {
				LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
				popupView = inflater.inflate(R.layout.task_popup,
						(ViewGroup) findViewById(R.id.task_popup));

				Display display = getWindowManager().getDefaultDisplay();
				int width = display.getWidth();
				int height = display.getHeight();

				addPopup = new PopupWindow(popupView, width, height, true);
				addPopup.showAtLocation(popupView, Gravity.CENTER, 0, 0);
				final EditText taskNameInput = (EditText) popupView
						.findViewById(R.id.taskname_input);
				final EditText taskDetailsInput = (EditText) popupView
						.findViewById(R.id.taskdetails_input);
				final EditText taskCategoryInput = (EditText) popupView
						.findViewById(R.id.tasklabel_input);
				final TextView resultText = (TextView) popupView
						.findViewById(R.id.addTaskResultText);
				// final DatePicker datePicker = (DatePicker) popupView
				// .findViewById(R.id.datePicker1);

				final EditText dateInput = (EditText) popupView
						.findViewById(R.id.dueDate);

				final SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd");
				dateInput.setText(sdf.format(new Date()));

				final TimePicker timePicker = (TimePicker) popupView
						.findViewById(R.id.timePicker1);
				
				timePicker.setCurrentHour(0);
				timePicker.setCurrentMinute(0);
				
				if (!category.equals("All")) {
					taskCategoryInput.setEnabled(false);
					taskCategoryInput.setText(category);
				}
				
				if(category.equals("Today"))
				{
					dateInput.setEnabled(false);
				}
				
				Button cancelButton = (Button) popupView
						.findViewById(R.id.taskpopup_cancel_button);
				Button okButton = (Button) popupView
						.findViewById(R.id.taskpopup_ok_button);
				cancelButton.setOnClickListener(new OnClickListener() {
					@Override
					public void onClick(View view) {
						addPopup.dismiss();
					}
				});
				okButton.setOnClickListener(new OnClickListener() {

					@Override
					public void onClick(View view) {

						String taskCategory;
						if (!category.equals("All")) {
							taskCategory = category;
						} else
							taskCategory = taskCategoryInput.getText()
									.toString();
						// System.err.println(taskCategory);
						String taskName = taskNameInput.getText().toString();
						String taskDetails = taskDetailsInput.getText()
								.toString();
						String dueDate = dateInput.getText().toString();

						String result = validate(taskName, taskDetails,
								taskCategory, dueDate);
						Date date = null;

						if (result == null) {
							try {
								date = sdf.parse(dueDate);
								int hour = timePicker.getCurrentHour();
								int minute = timePicker.getCurrentMinute();
								date.setHours(hour);
								date.setMinutes(minute);
							} catch (ParseException e) {
								// TODO Auto-generated catch block 
								e.printStackTrace();
							}

							tasksSource.createTask(userid, taskName,
									taskDetails, taskCategory,
									new Location(""), date);
							loadTasks(category);
							addPopup.dismiss();

						} else {
							resultText.setText(result);
						}
					}

				});
			}
		});
		
		if(category.equals("Completed"))
		{
			addTaskButton.setVisibility(View.GONE);
			uncompletedButton.setVisibility(View.GONE);
		}
	}

	/**
	 * loadTasks displays the appropriate tasks derived from a specified
	 * category. Additionally this method is capable of filtering tasks by date
	 * and completion
	 * 
	 * @param category
	 *            - the Category enumerated
	 */
	private void loadTasks(String category) {
		List<Task> result;
		if (category.equals("All") || category.equals("Today") || category.equals("Completed"))
		{
			result = tasksSource.getAllTasks(userid);
		} else {
			result = tasksSource.getCategoryTasks(userid, category);
		}
		Iterator<Task> itr = result.iterator();
		while (itr.hasNext()) {
			Task task = itr.next();
			if (filter == FilterType.DATE && task.dueDate.getTime() < filterDate.getTime())
			{
				itr.remove(); 
			}
			else if(filter == FilterType.TODAY)
			{
				SimpleDateFormat formatter = new SimpleDateFormat("yyyy/MM/dd");
				
				String taskDueDate = formatter.format(task.dueDate);
				String todayDate = formatter.format(filterDate);
				
				if(taskDueDate.compareTo(todayDate) != 0)
				{
					itr.remove();
				}
			}
			else if (filter == FilterType.UNCOMPLETED && task.completed)
			{
				itr.remove();
			}
			else if (filter == FilterType.COMPLETED && !task.completed)
			{
				itr.remove();
			}
		}
		tasks = new Task[result.size()];
		result.toArray(tasks);
		listAdapter = new TaskListAdapter(tasksSource, this,
				R.layout.task_list_item, tasks);
		listView.setAdapter(listAdapter);
		listView.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
		listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {

			@Override 
			public void onItemClick(AdapterView<?> parent, View view,
					int position, long id) {
				if (selected.contains(view)) {
					selected.remove(view);
					selectedids.add(listAdapter.getItem(position).uniqueID);
					view.setBackgroundColor(Color.WHITE);
				} else {
					selected.add(view);
					selectedids.add(listAdapter.getItem(position).uniqueID);
					view.setBackgroundColor(Color.rgb(255, 140, 0));
				}

			}
		});
	}

	/**
	 * validate determines that the required input fields have been entered
	 * 
	 * @param taskName
	 *            - the Task's name
	 * @param taskDetails
	 *            - the Task's details
	 * @param taskCategory
	 *            - the Task's label, "category", only checked when "All"
	 *            category is specified
	 * @return
	 */
	private String validate(String taskName, String taskDetails,
			String taskCategory, String dueDate) {
		Log.d("kefu", "inside validate");

		if (!taskName.isEmpty() && !taskDetails.isEmpty()
				&& !taskCategory.isEmpty() && !dueDate.isEmpty()) {

			SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd");

			// declare and initialize testDate variable, this is what will hold
			// our converted string

			Date testDate = null;

			// we will now try to parse the string into date form
			try {
				testDate = sdf.parse(dueDate);
			}

			// if the format of the string provided doesn't match the format we
			// declared in SimpleDateFormat() we will get an exception

			catch (ParseException e) {
				return "Due date should be in yyyy/MM/dd format";
			}

			// dateformat.parse will accept any date as long as it's in the
			// format
			// you defined, it simply rolls dates over, for example, december 32
			// becomes jan 1 and december 0 becomes november 30
			// This statement will make sure that once the string
			// has been checked for proper formatting that the date is still the
			// date that was entered, if it's not, we assume that the date is
			// invalid

			if (!sdf.format(testDate).equals(dueDate)) {
				return "The date that you provided is invalid.";
			}
			return null;

			// if we make it to here without getting an error it is assumed that
			// the date was a valid one and that it's in the proper format

			// String regEx =
			// "^(19|20)\\d{2}[- /.](0[1-9]|[12][0-9]|3[01])[- /.](0[1-9]|1[012])$";//
			// (19|20)\\d{2}$
			// Matcher matcherObj = Pattern.compile(regEx).matcher(dueDate);
			//
			// if (matcherObj.matches()) {
			// Log.d("kefu", "null");
			// return null;
			// } else {
			// Log.d("kefu", "datewrong");
			// return "Due date should be in yyyy/MM/dd format";
			//
			// }
		} else {
			Log.d("kefu", "field");

			return "All fields are required.";
		}
	}
	//for testing
	public View getPopup()
	{
		return popupView;
	}
	public Task[] getTasks()
	{
		return tasks;
	}
}